﻿using Autofac;
using Autofac.Extensions.DependencyInjection;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging;
using Newtonsoft.Json;
//using CNative.Apm.Skywalking.Abstractions.Common.Tracing;
//using CNative.Apm.Skywalking.Abstractions.Tracing;
using CNative.Cloud.Caching.Configurations;
using CNative.Cloud.CPlatform.Diagnostics;
using CNative.Cloud.CPlatform.Transport.Implementation;
using CNative.Cloud.CPlatform.Utilities;
using CNative.Cloud.EventBusRabbitMQ.Configurations;
using CNative.Cloud.ProxyGenerator;
using CNative.IModuleServices.Common;
using CNative.IModuleServices.Common.Models;
using CNative.IModuleServices.Common.Models.Events;
using CNative.IModuleServices.User;
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Threading.Tasks;
using CNative.Cloud.CPlatform;

namespace CNative.Services.Client
{
    public class Startup
    {
        //private ContainerBuilder _builder;
        //public Startup(IConfigurationBuilder config)
        //{
        //    ConfigureEventBus(config);
        //    ConfigureCache(config);
        //}

        //public IContainer ConfigureServices(ContainerBuilder builder)
        //{
        //    var services = new ServiceCollection();
        //    ConfigureLogging(services);
        //    builder.Populate(services);
        //    _builder = builder;
        //    ServiceLocator.Current = builder.Build();
        //    return ServiceLocator.Current;
        //}

        //public void Configure(IContainer app)
        //{

        //}

        #region 私有方法
        /// <summary>
        /// 配置日志服务
        /// </summary>
        /// <param name="services"></param>
        private void ConfigureLogging(IServiceCollection services)
        {
            services.AddLogging();
        }

        private static void ConfigureEventBus(IConfigurationBuilder build)
        {
            build
            .AddEventBusFile("eventBusSettings.json", optional: false);
        }

        /// <summary>
        /// 配置缓存服务
        /// </summary>
        private void ConfigureCache(IConfigurationBuilder build)
        {
            build
              .AddCacheFile("cacheSettings.json", optional: false);
        }

        /// <summary>
        /// 测试
        /// </summary>
        /// <param name="serviceProxyFactory"></param>
        public static void Test(IServiceProxyFactory serviceProxyFactory)
        {
            //var  tracingContext =  ServiceLocator.GetService<ITracingContext>();
            Task.Run(async () =>
            {
                RpcContext.GetContext().SetAttachment("xid",124);

                var userProxy = serviceProxyFactory.CreateProxy<IUserService>();
                var managerProxy = serviceProxyFactory.CreateProxy<IManagerService>();

                //var asyncProxy = serviceProxyFactory.CreateProxy<IAsyncService>();
                //var result= await  asyncProxy.AddAsync(1, 2);
                var user = userProxy.GetUser(new UserModel {
                    UserId = 1,
                    Name = "stone",
                    Age=120,
                     Sex=0
                }).GetAwaiter().GetResult();
                var e = userProxy.SetSex(Sex.Woman).GetAwaiter().GetResult();
                var v = userProxy.GetUserId("stone").GetAwaiter().GetResult();
                var fa = userProxy.GetUserName(1).GetAwaiter().GetResult();
                //userProxy.Try().GetAwaiter().GetResult();
                var v1 = userProxy.GetUserLastSignInTime(1).Result;
                var things = userProxy.GetAllThings().Result;
                var apiResult = userProxy.GetApiResult().GetAwaiter().GetResult();
                try
                {
                    userProxy.PublishThroughEventBusAsync(new UserEvent
                    {
                        UserId = 1,
                        Name = "stone"
                    }).Wait();

                    //userProxy.PublishThroughEventBusAsync(new UserEvent
                    //{
                    //    UserId = 1,
                    //    Name = "stone"
                    //}).Wait();
                }
                catch (Exception ex) { ConsoleC.WriteLine(ex); }

                var r = await userProxy.GetDictionary();
                var serviceProxyProvider = ServiceLocator.GetService<IServiceProxyProvider>();

                var bb = await managerProxy.SayHello("XJH_");
                Console.WriteLine($"SayHello：{bb}");

                const int noOfClients = 10000;
                var tasks = new Task[noOfClients];

                Console.WriteLine($"Press any key to continue,将循环调用{noOfClients}次...");
                Console.ReadLine();
                do
                {
                    Console.WriteLine($"正在循环 {noOfClients}次调用 GetUser.....");
                    //1w次调用
                    var watch = Stopwatch.StartNew();
                    for (var i = 0; i < noOfClients; i++)
                    {
                        tasks[i] = Task.Factory.StartNew((object clientNo) =>
                        {
                            try
                            {
                                //System.Threading.Thread.Sleep(100);
                                //var a = userProxy.GetDictionary().Result;

                                var a = userProxy.GetDictionary2(new UserModel
                                {
                                    Name = "stone",
                                    Age = 12,
                                    UserId = 2,
                                    Sex = Sex.Woman
                                },i).Result;
                                Console.WriteLine($"GetDictionary2：{a.UserId},{a.Name}");

                                var b = managerProxy.SayHello("XJH_" + clientNo).Result;
                                Console.WriteLine($"SayHello：{b}");
                                //var result = serviceProxyProvider.Invoke<object>(new Dictionary<string, object>(), "api/user/GetDictionary", "User").Result;
                            }
                            catch { System.Threading.Thread.Sleep(100); }
                        }, i + 1);
                    }
                    Task.WaitAll(tasks);

                    watch.Stop();
                    Console.WriteLine($"{noOfClients}次调用结束，执行时间：{watch.ElapsedMilliseconds}ms");
                    Console.WriteLine("Press any key to continue, q to exit the loop...");
                    var key = Console.ReadLine();
                    if (key.ToLower() == "q")
                        break;
                } while (true);
            }).Wait();
        }

        public static void TestRabbitMq(IServiceProxyFactory serviceProxyFactory)
        {
            var proxy = serviceProxyFactory.CreateProxy<IUserService>("User");
            proxy.PublishThroughEventBusAsync(new UserEvent()
            {
                Age = 18,
                Name = "stone",
                UserId = 1
            });
            //proxy.su
            Console.WriteLine("Press any key to exit...");
            Console.ReadLine();
        }

        public static void TestForRoutePath(IServiceProxyProvider serviceProxyProvider, IServiceProxyFactory serviceProxyFactory)
        {
            Dictionary<string, object> model = new Dictionary<string, object>();
            model.Add("user",new UserModel
            {
                Name = "stone",
                Age =12,
                UserId = 2,
                Sex = Sex.Woman
            });
            model.Add("id", 23);
            string path = "api/user/GetDictionary";
            string path2 = "api/user/GetDictionary2";
            string path3 = "api/manager/sayHello";
            string serviceKey = "User";

            Dictionary<string, object> model2 = new Dictionary<string, object>();
            model2.Add("name", "xjhfgggs");

            //var userProxy = serviceProxyProvider.Invoke<bool>(model, path, Cloud.CPlatform.Runtime.HttpMethod.GET).Result;
            //var userProxy2 = serviceProxyProvider.Invoke<UserModel>(model, path2,  Cloud.CPlatform.Runtime.HttpMethod.POST).Result;
           
            var userProxy3 = serviceProxyProvider.Invoke<string>(model2, path3, Cloud.CPlatform.Runtime.HttpMethod.GET).Result;
            ConsoleC.WriteLine($"SayHello：{userProxy3}", ConsoleColor.DarkGreen);

            var a2 = serviceProxyFactory.CreateProxy<IUserService>().GetDictionary2(new UserModel
            {
                Name = "stone",
                Age = 12,
                UserId = 2,
                Sex = Sex.Woman
            }, 32).Result;
            ConsoleC.WriteLine($"GetDictionary2：{a2.UserId},{a2.Name}", ConsoleColor.DarkCyan);

            var managerProxy = serviceProxyFactory.CreateProxy<IManagerService>();
            var bb = managerProxy.SayHello("XJH").Result;
            ConsoleC.WriteLine($"SayHello：{bb}",ConsoleColor.Green);

            //var userProxyi = serviceProxyFactory.CreateProxy<IUserService>("User");
            //Task.Run(async () =>
            //{
            //    var res = await userProxyi.GetDictionary2(new UserModel
            //    {
            //        UserId = 1,
            //        Name = "stone",
            //        Age = 120,
            //        Sex = 0
            //    }, 35);
            //});

            //var s = userProxy.Result;
            Console.WriteLine("Press any key to exit...");
            Console.ReadLine();
        }
        #endregion

    }
}
